package interaction

import (
	"time"

	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/app/sysparam"

	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/evt/userclievt"

	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/ddd"

	"github.com/gin-gonic/gin"
	"github.com/pkg/errors"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/common"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/factory"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/infod"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/interactiond"
)

type respInfo struct {
	InfoID       string         `json:"info_id"`
	Imgs         []string       `json:"imgs"`    // 图标
	Video        string         `json:"video"`   // 视频
	Tags         []string       `json:"tags" `   // 标签列表
	Content      string         `json:"content"` // 信息内容
	Creator      string         `json:"creator"`
	CreTime      time.Time      `json:"cre_time"`
	LastTime     time.Time      `json:"last_time"`     // 子评论最后评论时间
	LastReplayer string         `json:"last_replayer"` // 子评论最后评论人
	Totals       infoTotal      `json:"totals"`
	CtlParam     *infoCtrlParam `json:"ctl_param,omitempty"`
	My           my             `json:"my"` // 和我相关的信息
}
type infoTotal struct {
	LikeNum   int `json:"like_num"`
	CollNum   int `json:"coll_num"`
	ReplayNum int `json:"replay_num"` // 子评论数量
}
type my struct {
	Like bool `json:"like"`
	Coll bool `json:"coll"`
}
type infoCtrlParam struct {
	IsReply int `json:"is_reply"` // 是否开启信息评论 0 不开启 1 开启
	IsShare int `json:"is_share"` // 是否开启分享 0 不开启 1 开启
	IsLike  int `json:"is_like"`
	IsColl  int `json:"is_coll"`
}

// 分页获取信息列表
func (c interactionCtrl) queryPageInfos(ctx *gin.Context) {

	page := c.GetPageInfo(ctx, common.PageModeID)
	dctx := c.DDDContext(ctx)
	sch := c.geIntInfoSearch(ctx)
	if sch.ColumnID == "" {
		c.ErrBadRequest(ctx, 1, "未指定栏目不能加载互动信息")
		return
	}
	pr, respInfos, err := c._queryPageInfos(dctx, page, sch)
	if err != nil {
		c.ErrServerError(ctx, 2, "查询失败", err)
		return
	}
	c.SuccessPage(ctx, page, pr, respInfos)
}

// 分页获取信息列表
func (c interactionCtrl) queryInfoCount(ctx *gin.Context) {
	dctx := c.DDDContext(ctx)
	sch := c.geIntInfoSearch(ctx)
	if sch.ColumnID == "" {
		c.ErrBadRequest(ctx, 1, "未指定栏目不能加载互动信息")
		return
	}
	num, err := c.iar.QueryNum(dctx, sch)
	if err != nil {
		c.ErrServerError(ctx, 2, "查询失败", err)
		return
	}
	c.Success(ctx, map[string]int{"count": num})
}

// 获取信息
func (c interactionCtrl) queryInfo(ctx *gin.Context) {
	dctx := c.DDDContext(ctx)
	columnID := ctx.Param("columnid")
	if columnID == "" {
		c.ErrBadRequest(ctx, 1, "互动栏目不存在")
		return
	}
	infoid := ctx.Param("infoid")
	if infoid == "" {
		c.ErrBadRequest(ctx, 2, "互动信息不存在")
		return
	}
	g, err := factory.DefaultFactory.GetOrCreIGroup(dctx, interactiond.IGTTInfo, infoid)
	if err != nil {
		c.ErrServerError(ctx, 5, "获取互动组信息失败", errors.Wrap(err, "获取互动组信息失败"))
		return
	}
	ia, err := c.iar.GetInfo(dctx, infoid)
	if err != nil {
		c.ErrServerError(ctx, 3, "查找信息失败", errors.Wrap(err, "查找信息列表失败"))
		return
	}
	if ia == nil {
		c.ErrNotFound(ctx, 4, "信息不存在")
		return
	}
	var respInfo = respInfo{
		InfoID:  ia.InfoID,
		Tags:    ia.Tags,
		Content: ia.Content,
		Imgs:    ia.Icon,
		Creator: ia.Creator,
		CreTime: ia.CreTime,
	}
	if sp, ok := ia.Extras["sp"]; ok {
		v := sp.(string)
		respInfo.Video = v
	}
	intTypeLikeCode := sysparam.IntsLikeCode()
	intTypeCollCode := sysparam.IntsCollectionCode()
	for _, v := range g.GroupTotal {
		switch v.ITCode {
		case intTypeLikeCode:
			respInfo.Totals.LikeNum = v.Total
		case intTypeCollCode:
			respInfo.Totals.CollNum = v.Total
		default:
		}
	}
	respInfo.Totals.ReplayNum = g.ReplayNum
	respInfo.LastReplayer = g.LastReplayer
	respInfo.LastTime = g.LastTime
	respInfo.CtlParam = &infoCtrlParam{IsReply: g.IsReplay, IsShare: 1}

	for _, v := range g.AllowCodes {
		switch v {
		case intTypeLikeCode:
			respInfo.CtlParam.IsLike = 1
		case intTypeCollCode:
			respInfo.CtlParam.IsColl = 1
		}
	}

	_, rs, err := c.iiar.QueryPage(dctx, interactiond.InteractionSearch{
		UID:   []string{dctx.UID()},
		IGID:  []string{g.IGID},
		Codes: []string{intTypeCollCode, intTypeLikeCode},
	}, common.PageInfo{PageSize: 2})
	if err != nil {
		c.ErrServerError(ctx, 3, "获取和我相关的属性失败", errors.Wrap(err, "获取和我相关的属性失败"))
		return
	}
	for _, v := range rs {
		switch v.Code {
		case intTypeLikeCode:
			respInfo.My.Like = true
		case intTypeCollCode:
			respInfo.My.Coll = true
		}
	}
	c.Success(ctx, respInfo)
	userclievt.TriggerLookInfoEvent(ctx.Request.RequestURI, dctx.UID(), interactiond.IGTTInfo, infoid)
}

// 获取互动信息查询条件
func (c interactionCtrl) geIntInfoSearch(ctx *gin.Context) (result infod.InfoSearch) {

	result.ColumnID = ctx.Param("columnid")
	result.Key = ctx.DefaultQuery("key", "")
	result.Tags, _ = ctx.GetQueryArray("tags")
	result.Status = []infod.IStatus{infod.IStatusPublished}
	return
}

// 分页获取我的信息列表
func (c interactionCtrl) queryPageMyInfos(ctx *gin.Context) {

	page := c.GetPageInfo(ctx, common.PageModeID)
	dctx := c.DDDContext(ctx)
	sch := c.geIntInfoSearch(ctx)
	if sch.ColumnID == "" {
		c.ErrBadRequest(ctx, 1, "未指定栏目不能加载互动信息")
		return
	}
	sch.Creator = dctx.UID()
	pr, respInfos, err := c._queryPageInfos(dctx, page, sch)
	if err != nil {
		c.ErrServerError(ctx, 2, "查询失败", err)
		return
	}
	c.SuccessPage(ctx, page, pr, respInfos)
}

// 分页获取其他用户的互动信息列表
func (c interactionCtrl) queryPageOtherInfos(ctx *gin.Context) {

	page := c.GetPageInfo(ctx, common.PageModeID)
	dctx := c.DDDContext(ctx)
	sch := c.geIntInfoSearch(ctx)
	if sch.ColumnID == "" {
		c.ErrBadRequest(ctx, 1, "未指定栏目不能加载互动信息")
		return
	}
	uid := ctx.Param("uid")
	if uid == "" {
		c.ErrBadRequest(ctx, 2, "未指定查询用户")
		return
	}
	sch.Creator = uid
	pr, respInfos, err := c._queryPageInfos(dctx, page, sch)
	if err != nil {
		c.ErrServerError(ctx, 2, "查询失败", err)
		return
	}
	c.SuccessPage(ctx, page, pr, respInfos)
}

// 分页获取我的信息列表
func (c interactionCtrl) _queryPageInfos(dctx ddd.Context, page common.PageInfo, sch infod.InfoSearch) (pr common.PageResult, respInfos []respInfo, err error) {

	pr, cs, err := c.iar.QueryPage(dctx, sch, page)
	if err != nil {
		err = errors.Wrap(err, "查找信息列表失败")
		return
	}

	respInfos = make([]respInfo, 0, len(cs))
	for _, v := range cs {

		ri := respInfo{
			InfoID:  v.InfoID,
			Tags:    v.Tags,
			Content: v.Content,
			Imgs:    v.Icon,
			Creator: v.Creator,
			CreTime: v.CreTime,
		}
		if sp, ok := v.Extras["sp"]; ok {
			v := sp.(string)
			ri.Video = v
		}
		g, err1 := factory.DefaultFactory.GetOrCreIGroup(dctx, interactiond.IGTTInfo, v.InfoID)
		if err1 != nil {
			err = errors.Wrap(err1, "获取互动信息组失败．")
			return
		}
		intTypeLikeCode := sysparam.IntsLikeCode()
		intTypeCollCode := sysparam.IntsCollectionCode()
		for _, v := range g.GroupTotal {
			switch v.ITCode {
			case intTypeLikeCode:
				ri.Totals.LikeNum = v.Total
			case intTypeCollCode:
				ri.Totals.CollNum = v.Total
			default:
			}
		}
		ri.Totals.ReplayNum = g.ReplayNum
		ri.LastReplayer = g.LastReplayer
		ri.LastTime = g.LastTime

		_, rs, err1 := c.iiar.QueryPage(dctx, interactiond.InteractionSearch{
			UID:   []string{dctx.UID()},
			IGID:  []string{g.IGID},
			Codes: []string{intTypeCollCode, intTypeLikeCode},
		}, common.PageInfo{PageSize: 2})
		if err1 != nil {
			err = errors.Wrap(err, "获取和我相关的属性失败")
			return
		}
		for _, v := range rs {
			switch v.Code {
			case intTypeLikeCode:
				ri.My.Like = true
			case intTypeCollCode:
				ri.My.Coll = true
			default:
			}
		}
		respInfos = append(respInfos, ri)
	}
	return
}
